package com.zhuoyian.dl.service;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import com.zhuoyian.dl.model.DLVO;
import com.zhuoyian.dl.util.ConnUtil;
import com.zhuoyian.dl.util.DownloadLog;

/**
 * �����߳���
 * 
 * @author Administrator
 * 
 */
public class DownloadTask implements Runnable {
	private final static Object syncObj = new Object();
	private URL url;
	private int downLength;
	private boolean finish = false;
	private DLVO dlModel;
	private RandomAccessFile raf = null;
	private boolean interrupt;

	/**
	 * 
	 */
	public DownloadTask(DLVO dlModel, URL downUrl) {
		this.url = downUrl;
		this.dlModel = dlModel;
		downLength = (int) dlModel.getDownSize();
		interrupt=false;
	}

	@Override
	public void run() {
		int block = (int) (dlModel.getEndSize() - dlModel.getStartSize());
		if (downLength < block) {// δ�������
			int startPos = (int) (dlModel.getStartSize() + dlModel
					.getDownSize());// ��ʼλ��
			// ʹ��Get��ʽ����
			HttpURLConnection http = ConnUtil.connect(url, startPos,
					(int) dlModel.getEndSize());
			InputStream inStream = null;

			try {
				inStream = http.getInputStream();
				byte[] buffer = new byte[1024];
				int offset = 0;
				raf = new RandomAccessFile(dlModel.getLocalPath(), "rw");
				raf.seek(startPos);
				while ((offset = inStream.read(buffer)) != -1) {
					writeFile(buffer, offset);
					downLength += offset;
					if(interrupt){
						return;
					}
				}
				DownloadLog.print("Thread " + dlModel.getTaskId()
						+ " download finish");
				this.finish = true;
				close(http, inStream);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				this.downLength = -1;
				close(http, inStream);
			} catch (IOException e) {
				e.printStackTrace();
				this.downLength = -1;
				close(http, inStream);
			} 
		}
	}
	
	private void close(HttpURLConnection http,InputStream inStream){
		
		if (http != null) {
			http.disconnect();
			http = null;
		}
		if (inStream != null) {
			try {
				inStream.close();
				inStream = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (raf != null) {
			try {
				raf.close();
				raf = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public DLVO getDlModel() {
		return dlModel;
	}

	/**
	 * �����Ƿ����
	 * 
	 * @return
	 */
	public boolean isFinish() {
		return finish;
	}

	/**
	 * �Ѿ����ص����ݴ�С
	 * 
	 * @return �������ֵΪ-1,��������ʧ��
	 */
	public int getDownLength() {
		return downLength;
	}
	
	

	public boolean isInterrupt() {
		return interrupt;
	}

	public void setInterrupt(boolean interrupt) {
		this.interrupt = interrupt;
	}

	/**
	 * д������
	 * 
	 * @param buffer
	 * @param offset
	 * @throws IOException
	 */
	private void writeFile(byte[] buffer, int offset) throws IOException {
		if (raf == null) {
			return;
		}
		synchronized (syncObj) {
			raf.write(buffer, 0, offset);
		}
	}
}
